#include "application.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>



Application* Application::instance = nullptr;
Application* Application::getInstance() {
	if (!instance)
	{
		instance = new Application();
	}
	return instance;
}

Application::Application() {

}
Application::~Application() {
}

bool Application::init(const int& width, const int& height) {
    this->width = width;
    this->height = height;
    //1、 初始化GLFW
    glfwInit();
    //设置主版本号
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    //设置次版本号
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    //设置为核心模式(非立即渲染模式)
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //2、 创建一个窗口对象
    this->window = glfwCreateWindow(this->width, this->height, "OpenGL", NULL, NULL);

    if (this->window == nullptr)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return false;
    }
    glfwSetWindowUserPointer(this->window, this);
    //设置窗口为OPENGL绘制平台
    glfwMakeContextCurrent(this->window);

    //设置窗口大小变化回调
    glfwSetFramebufferSizeCallback(this->window, Application::frameBufferSizeCallback);
    //设置键盘事件
    glfwSetKeyCallback(this->window, keyCallback);

    /*使用glad加载所有当前版本opengl的函数*/
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Faild to initialize GLAD\n";
        return false;
    }
    return true;

}

bool Application::update() {
    if(glfwWindowShouldClose(this->window)){
        return false;
    }
    //接收并分发窗体消息
    glfwPollEvents();
    //执行双缓存切换
    glfwSwapBuffers(this->window);
    return true;
}

bool Application::destroy() {
    //// 终止GLFW
   glfwTerminate();
    return true;
}

void Application::frameBufferSizeCallback(GLFWwindow* window, int width, int height) {
    glViewport(0, 0, width, height);//视图大小
    std::cout << "changed" << std::endl;
    Application* self = (Application*)glfwGetWindowUserPointer(window);
    if (self->resizeCallback != nullptr)
    {
        self->resizeCallback(width, height);
    }
}

void Application::keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    Application* self = (Application*)glfwGetWindowUserPointer(window);
    if (self->keyBoardCallback != nullptr) {
        self->keyBoardCallback(key, action, mods);
    }
}